/* 
 * File:   main.cpp
 * Author: Tung Mai
 *
 * Created on June 24, 2010, 11:56 AM
 */

#include <QuickTime/QuickTime.h>

void Cleanup(SeqGrabComponent sg, SGChannel channel, Handle dataRef,
        PicHandle picHandle, GraphicsExportComponent ge)
{
    if (ge)
        CloseComponent(ge);

    if (picHandle)
        delete *picHandle; // dereference to *Picture

    if (dataRef)
    {
        DisposeHandle(dataRef);
    }

    if (sg && channel)
    {
        SGDisposeChannel(sg, channel);
    }

    if (sg)
    {
        CloseComponent(sg);
    }
}

int main(int argc, char** argv)
{
    if (argc < 2)
    {
        printf("Not enough arguments\n");
        return 1;
    }

    char *szFilePath = argv[1];

    OSStatus err = noErr;
    SeqGrabComponent seqGrab = NULL;
    PicHandle pictureHandle = NULL;
    GraphicsExportComponent graphicsExporter = NULL;
    Rect bounds;
    SGChannel frameChannel;
    Handle dataRef;
    OSType dataRefType;

    err = OpenADefaultComponent(SeqGrabComponentType, 0, &seqGrab);
    if (err)
    {
        printf("Error: OpenADefaultComponent() returned no sequence grabber component!\n");
        Cleanup(seqGrab, NULL, NULL, NULL, NULL);
        return 1;
    }

    err = SGInitialize(seqGrab);
    if (err)
    {
        printf("Error: Init sequence grabber component failed!\n");
        Cleanup(seqGrab, NULL, NULL, NULL, NULL);
        return 1;
    }

    bounds.top = 0;
    bounds.left = 0;
    bounds.right = 640;
    bounds.bottom = 480;

    // initializes channels
//    result = SGNewChannel(seqGrab, VideoMediaType, &info.frameChannel);
    err = SGNewChannel(seqGrab, VideoMediaType, &frameChannel);
    if(err)
    {
        printf("SGNewChannel failed for VideoMediaType.\n");
        Cleanup(seqGrab, NULL, NULL, NULL, NULL);
        return 2;
    }

    err = SGSetChannelBounds(frameChannel, &bounds);
    if(err)
    {
        printf("SGSetChannelBounds failed.\n");
        Cleanup(seqGrab, frameChannel, NULL, NULL, NULL);
        return 3;
    }

    err = SGSetChannelUsage(frameChannel, seqGrabRecord);
    if(err)
    {
        printf("SGSetChannelUsage failed.\n");
        Cleanup(seqGrab, frameChannel, NULL, NULL, NULL);
        return 4;
    }

    int i;

    for (i = 0; i < 1; i++)
    {
        CFStringRef cfFileName = NULL;
        cfFileName = CFStringCreateWithCString(kCFAllocatorDefault, szFilePath, kCFStringEncodingASCII);
        if (!cfFileName)
        {
            printf("CFStringCreateWithCString failed!\n");
            Cleanup(seqGrab, frameChannel, NULL, NULL, NULL);
            return 5;
        }

        err = QTNewDataReferenceFromFullPathCFString(cfFileName, kQTNativeDefaultPathStyle,
                0, &dataRef, &dataRefType);
        if (err)
        {
            printf("Error: could not create a data reference for filename: %s\n", szFilePath);
            Cleanup(seqGrab, frameChannel, NULL, NULL, NULL);
            return 6;
        }

        CFRelease(cfFileName);

		err = SGGrabPict(seqGrab, &pictureHandle, &bounds, 0, grabPictOffScreen);
		if (err)
		{
			printf("Error: SGGrabPict() returned error %ld!\n", err);
            Cleanup(seqGrab, frameChannel, dataRef, NULL, NULL);
			return 7;
		}

        err = OpenADefaultComponent(GraphicsExporterComponentType, kQTFileTypeJPEG, &graphicsExporter);
        if (err)
        {
            printf("Error: OpenADefaultComponent() returned no graphics export component!\n");
            Cleanup(seqGrab, frameChannel, dataRef, pictureHandle, NULL);
            return 8;
        }

        err = GraphicsExportSetInputPicture(graphicsExporter, pictureHandle);
        if (err)
        {
            printf("GraphicsExportSetInputPicture failed!\n");
            Cleanup(seqGrab, frameChannel, dataRef, pictureHandle, graphicsExporter);
            return 9;
        }

        // use data reference for output
        err = GraphicsExportSetOutputDataReference(graphicsExporter, dataRef, dataRefType);
        if (err)
        {
            printf("GraphicsExportSetOutputDataReference failed!\n");
            Cleanup(seqGrab, frameChannel, dataRef, pictureHandle, graphicsExporter);
            return 10;
        }


        err = GraphicsExportDoExport(graphicsExporter, NULL);
        if (err)
        {
            printf("GraphicsExportDoExport failed!\n");
            Cleanup(seqGrab, frameChannel, dataRef, pictureHandle, graphicsExporter);
            return 11;
        }
	}

    Cleanup(seqGrab, frameChannel, dataRef, pictureHandle, graphicsExporter);
    printf("Finished\n");
    return (EXIT_SUCCESS);
}

